import { Caller } from "../core/call/Caller";
import { ResourceManager } from "./ResourceManager";
import { Log } from "../debug/Log";
import { ResourceInfo } from "info/ResourceInfo";
import { LoaderManager } from "./LoaderManager";
import { Global } from "../global/Global";
import { LoaderErrorEvent } from "loader/LoaderErrorEvent";
//class PreLoaderManager
    
    export  class PreLoaderManager /* flash.events.EventDispatcher */
    {
        constructor()
        {
            
            if (PreLoaderManager._instance != null) 
            {
                throw new Error("LoaderManager 单例  ");
            }
            this._queueArray = [];
            this._completeCaller = new Caller();
            this._errorCaller = new Caller();
            this._urlLoader = new Object /* flash.net.URLLoader */();
            return;
        }

        public start(): void
        {
            this.loadNext();
            return;
        }

        public preLoad(arg1: string, arg2: Object=null): void
        {
            var loc1=ResourceManager.getInfoByName(arg1);
            if (loc1 == null) 
            {
                Log.error(arg1 + "==没有该文件");
                return;
            }
            if (arg2) 
            {
                loc1.extData = arg2;
            }
            if (loc1.isLoaded || loc1.isLoading || loc1.isAddToPreLoad) 
            {
                return;
            }
            this.addQueue(loc1);
            return;
        }

        /* internal  */loadResource(arg1: ResourceInfo): Boolean
        {
            if (!LoaderManager.instance.isLoading() && !this._isLoading) 
            {
                this._isLoading = true;
                arg1.isPreLoading = true;
                this._currentResInfo = arg1;
                this._urlLoader.dataFormat = flash.net.URLLoaderDataFormat.BINARY;
                this._urlLoader.addEventListener(flash.events.Event.COMPLETE, this.onCompleteHandler);
                this._urlLoader.addEventListener(flash.events.ProgressEvent.PROGRESS, this.onProgressHandler);
                this._urlLoader.addEventListener(flash.events.IOErrorEvent.IO_ERROR, this.onIOError);
                this._urlLoader.addEventListener(flash.events.SecurityErrorEvent.SECURITY_ERROR, this.onIOError);
                this._urlLoader.load(new Object /* flash.net.URLRequest */(arg1.path));
                return true;
            }
            return false;
        }

        /* internal  */addQueue(arg1: ResourceInfo): void
        {
            arg1.isAddToPreLoad = true;
            if (this.loadResource(arg1) == false) 
            {
                this._queueArray.push(arg1);
            }
            return;
        }

        protected loadNext(): void
        {
            var loc1=null;
            if (this._queueArray.length > 0) 
            {
                loc1 = this._queueArray[0] as ResourceInfo;
                if (loc1.isLoaded || loc1.isLoading) 
                {
                    this._queueArray.shift();
                    this.loadNext();
                }
                else if (this.loadResource(loc1)) 
                {
                    this._queueArray.shift();
                }
            }
            return;
        }

        protected onCompleteHandler(arg1: Object /* flash.events.Event */): void
        {
            try 
            {
                this._urlLoader.removeEventListener(flash.events.Event.COMPLETE, this.onCompleteHandler);
                this._urlLoader.removeEventListener(flash.events.ProgressEvent.PROGRESS, this.onProgressHandler);
                this._urlLoader.removeEventListener(flash.events.IOErrorEvent.IO_ERROR, this.onIOError);
                this._urlLoader.removeEventListener(flash.events.SecurityErrorEvent.SECURITY_ERROR, this.onIOError);
                this._urlLoader.close();
            }
            catch (e)
            {
            };
            if (this._currentResInfo) 
            {
                this._currentResInfo.cacheBytes = arg1.target.data;
            }
            this._isLoading = false;
            this._currentResInfo.isPreLoading = false;
            this._completeCaller.call(this._currentResInfo.name);
            this.loadNext();
            return;
        }

        protected onProgressHandler(arg1: Object /* flash.events.ProgressEvent */): void
        {
            dispatchEvent(arg1);
            return;
        }

        /* internal  */onIOError(arg1: Object /* flash.events.ErrorEvent */): void
        {
            this._urlLoader.removeEventListener(flash.events.Event.COMPLETE, this.onCompleteHandler);
            this._urlLoader.removeEventListener(flash.events.ProgressEvent.PROGRESS, this.onProgressHandler);
            this._urlLoader.removeEventListener(flash.events.IOErrorEvent.IO_ERROR, this.onIOError);
            this._urlLoader.removeEventListener(flash.events.SecurityErrorEvent.SECURITY_ERROR, this.onIOError);
            this.onIOErrorHandler(arg1);
            this._currentResInfo.isPreLoading = false;
            this._errorCaller.call(this._currentResInfo.name);
            this.loadNext();
            return;
        }

        protected onIOErrorHandler(arg1: Object /* flash.events.ErrorEvent */): void
        {
            Log.system(arg1.text);
            if (Global.isDebugModle) 
            {
                dispatchEvent(new LoaderErrorEvent(arg1.text));
            }
            return;
        }

        public addLoadedCall(arg1: string, arg2: Function): void
        {
            this._completeCaller.addCall(arg1, arg2);
            return;
        }

        public addErrorCall(arg1: string, arg2: Function): void
        {
            this._errorCaller.addCall(arg1, arg2);
            return;
        }

        public PreLoaderManager.get preloadingInfo(): ResourceInfo
        {
            if (this._currentResInfo && this._currentResInfo.isPreLoading) 
            {
                return this._currentResInfo;
            }
            return null;
        }

        public static get instance(): PreLoaderManager
        {
            return PreLoaderManager._instance;
        }

        private /* var */_urlLoader: Object /* flash.net.URLLoader */;

        private /* var */_isLoading: Boolean=false;

        private /* var */_completeCaller: Caller;

        private /* var */_errorCaller: Caller;

        private /* var */_currentResInfo: ResourceInfo;

        private /* var */_queueArray: Array<any>;

        private static /* var */_instance: PreLoaderManager;
    }

            PreLoaderManager._instance = new PreLoaderManager();
        